<?php
/**
 * 
 * $Id: QQLoginClass.inc.php 465 2012-08-02 03:15:01Z 5330056@qq.com $
 */
class QQLoginClass extends OauthBaseClass
{
	const QQLoginAppId = '100285537';
	const QQLoginAppKey = 'b6a53f61acbbb116e19ceee9e4ae1eb0';
	const QQAccessTokenKey = 'QQAccessTokenKeyBYiTuwang.com';
	private $accessToken = '';
	private $openID = '';
	static private $scope = array('get_user_info', 'add_share,list_album', 'add_album', 'upload_pic', 'add_topic', 'add_one_blog', 'add_weibo');
	static private $callbackUrl = 'http://common.ituwang.com/oAuthCallback.php';
	private $httpConnectionObj = false;
	public $cacheObj = false;
	
	public function __construct()
	{
		global $cacheObj;
		
		if(empty($cacheObj))
		{
			$this->cacheObj = $cacheObj = Bin::singtolen('CacheClass', 'Source');
		}
		else 
		{
			$this->cacheObj = $cacheObj;
		}
		
		if(!empty($_COOKIE['QQAccessToken']) && ($accessToken = Bin::execute('BinCryptClass::decrypt', $_COOKIE['QQAccessToken'], $this->getQQAccessTokenKey())))
		{
			$this->accessToken = $accessToken;
		}
		if(!empty($_COOKIE['QQOpenID']) && ($QQOpenID = Bin::execute('BinCryptClass::decrypt', $_COOKIE['QQOpenID'], $this->getQQAccessTokenKey())))
		{
			$this->openID = $QQOpenID;
		}
	}

	static public function getQQLoginAddress($callbackUrl = '', $scope = array(0))
	{
		$callbackUrl = urlencode(empty($callbackUrl) ? self::$callbackUrl : $callbackUrl);
		$url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=".self::QQLoginAppId."&redirect_uri={$callbackUrl}&scope=";
		foreach($scope as $k)
		{
			$url .= self::$scope[$k].',';
		}
		return trim($url, ', ').'&state='.self::createRandCode();
	}
	
	public function getAccessToken($authorizationCode = '', $callbackUrl = '')
	{
		if(empty($authorizationCode))
		{
			return $this->accessToken;
		}
		$callbackUrl = urlencode(empty($callbackUrl) ? self::$callbackUrl : $callbackUrl);
		$url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=".self::QQLoginAppId."&client_secret=".self::QQLoginAppKey."&code={$authorizationCode}&state=".$this->createRandCode()."&redirect_uri={$callbackUrl}";
		$rsData = str_replace('access_token=', '', $this->loopGetData($url));
		if(empty($rsData) || strpos($rsData, 'callback') !== false)
		{
			return false;
		}
		list($accessToken) = explode('&', $rsData);
		setcookie('QQAccessToken', Bin::execute('BinCryptClass::encrypt', $accessToken, $this->getQQAccessTokenKey()), time() + 86400 * 28 * 3, '/', G_CURRENT_DOMAIN);
		$this->accessToken = $accessToken;
		return $accessToken;
	}
	
	public function getOpenID($accessToken = '')
	{
		if(empty($accessToken))
		{
			return $this->openID;
		}
		$url = "https://graph.qq.com/oauth2.0/me?access_token={$accessToken}";
		$rsData = $this->loopGetData($url);
		if(preg_match('/"openid":"(.*)"/U', $rsData, $m))
		{
			$this->openID = $m[1];
			setcookie('QQOpenID', Bin::execute('BinCryptClass::encrypt', $m[1], $this->getQQAccessTokenKey()), time() + 86400 * 28 * 3, '/', G_CURRENT_DOMAIN);
			return $m[1];
		}
		return $rsData;
	}
	
	private function checkKey()
	{
		if(empty($this->openID) || empty($this->accessToken))
		{
			return false;
		}
		return true;
	}
	
	public function getUserInfo()
	{
		if($this->checkKey() == false)
		{
			return false;
		}
		
		$cacheKey = 'user-info::'.$this->getOpenID();
		$cacheData = $this->cacheObj->getCache($cacheKey);
		if(empty($cacheData))
		{
			$url = "https://graph.qq.com/user/get_user_info?access_token={$this->accessToken}&oauth_consumer_key=".self::QQLoginAppId."&openid=".$this->openID;
			$rsData = $this->loopGetData($url);
			if(!empty($rsData))
			{
				$rsData = converCharByArr(json_decode($rsData, true));
				$this->cacheObj->saveCache($cacheKey, $rsData, 3600 * 3);
				return $rsData;
			}
			return false;
		}
		return $cacheData;
	}
	
	private function loopGetData($url, $n = 3)
	{
		if(empty($this->httpConnectionObj))
		{
			$this->httpConnectionObj = Bin::singtolen('HttpConnectionClass', 'Source');
		}
		for($i = 0; $i < $n; $i ++)
		{
			$rsData = $this->httpConnectionObj->getData($url);
			if(!empty($rsData))
			{
				return $rsData;
			}
		}
		return $rsData;
	}
	
	public function getAppID()
	{
		return self::QQLoginAppId;
	}
	
	static private function createRandCode()
	{
		return createRandString().'-'.'QQ';
	}
	
	private function getQQAccessTokenKey()
	{
		return CommonClass::getCryptKey(self::QQAccessTokenKey);
	}
}
